/*
 *  MTouchware_control_receiver.c
 *
 *  This code monitors OSC messages received with from another application 
 *  and modifies the mtouchware behaviour.
 *
 *  Copyright (C) 2010 LIMSI-CNRS (Orsay-France) and EFREI (Paris-France)
 *
 *  Authors: Rami Ajaj, Nicolas Flasque and Frederic Vernier.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation; either version 2.1 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  $Id$
 */

#include "MTouchware_control_receiver.h"
#include "TUIO_receiver.h"

int control_done = 0;


void* MTouchware_control_receiver(void *arg)
{
  int lo_fd;
  fd_set rfds;
  struct timeval tv;
  int retval;
  
  /* start a new server on port CONTROL_IN_PORT */
  lo_server s = lo_server_new((char*)arg, error);
  
  printf("MTouchWare level 2 : you can control the parameter through OSC messages on port: %s \n", (char*)arg);
  
  /* add method that will match any path and args */
  lo_server_add_method(s, NULL, NULL, generic_control_handler, NULL);
  
  /* get the file descriptor of the server socket, if supported */
  lo_fd = lo_server_get_socket_fd(s);
  
  if (lo_fd > 0) {
    
    /* select() on lo_server fd is supported, so we'll use select()
     * to watch both stdin and the lo_server fd. */
    
    do {
      FD_ZERO(&rfds);
#ifndef WIN32
      FD_SET(0, &rfds);  /* stdin */
#endif
      FD_SET(lo_fd, &rfds);
      
      retval = select(lo_fd + 1, &rfds, NULL, NULL, NULL); /* no timeout */
      
      if (retval == -1) {
        
        printf("select() error\n");
        exit(1);
        
      } else if (retval > 0) {
        
        if (FD_ISSET(0, &rfds)) {
          
          read_stdin();
          
        }
        if (FD_ISSET(lo_fd, &rfds)) {
          
          lo_server_recv_noblock(s, 0);
          
        }
      }
      
    } while (!control_done);
    
  } else {
    
    /* lo_server protocol does not support select(), so we'll watch
     * stdin while polling the lo_server. */
#ifdef WIN32
    printf("non-blocking input from stdin not supported under Windows\n");
    exit(1);
#else
    do {
      
      FD_ZERO(&rfds);
      FD_SET(0, &rfds);
      tv.tv_sec = 0;
      tv.tv_usec = 10000;
      
      retval = select(1, &rfds, NULL, NULL, &tv); /* timeout every 10ms */
      
      if (retval == -1) {
        
        printf("select() error\n");
        exit(1);
        
      } else if (retval > 0 && FD_ISSET(0, &rfds)) {
        
        read_stdin();
        
      }
      
      lo_server_recv_noblock(s, 0);
      
    } while (!control_done);
#endif
  }
  
  return 0;
}

int generic_control_handler(const char *path, const char *types, lo_arg **argv,
                            int argc, void *data, void *user_data)
{
	int i;
	printf("GENERIC CONTROL HANDLER path: <%s> \n", path);
  for (i=0; i<argc; i++) {
		printf("arg %d '%c' ", i, types[i]);
		lo_arg_pp(types[i], argv[i]);
		printf("\n");
  }
  printf("\n");
  fflush(stdout);
  
  return 1;
}



